// AboutDlg.cpp : implementation of the CGroupsDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif
#include "groupsdlg.h"
#include "newnamedlg.h"
#include "membersdlg.h"
#include "membersdb.h"
#include "Utils.h"

CGroupsDlg::CGroupsDlg(void)
    : m_SelectedGroupId(0)
    , m_HideGroupId(0)
    , m_SelectMode(false)
{
}

LRESULT CGroupsDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    AtlCreateMenuBar(m_hWnd, IDM_NEW_DELETE);

#ifdef WIN32_PLATFORM_WFSP
    if (hMenuBar != NULL)
        AtlActivateBackKey(hMenuBar);
#endif

    BOOL Ret = m_ImageList.Create(32, 32, ILC_COLORDDB | ILC_MASK, 2, 0);
    ATLASSERT(Ret == TRUE);

    CIcon icon;
    icon.LoadIcon(IDI_GROUPS);
    int Result = m_ImageList.AddIcon(icon);
    ATLASSERT(Result != -1);
    icon.DestroyIcon();

    m_List.Attach(GetDlgItem(IDC_LIST));
    m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
    m_List.SetImageList(m_ImageList, LVSIL_SMALL);

    CRect r;
    m_List.GetClientRect(&r);
    m_List.InsertColumn(INDEX_NAME, NULL, LVCFMT_LEFT, r.Width());
    if (m_SelectMode == false)
        m_List.InsertColumn(INDEX_OP, NULL, LVCFMT_RIGHT, r.Width());

    m_GroupsDb.Open();

    UINT i = 1;     // 0th is reserved for saving current group name
    CString GroupName;
    UINT Id = 0;
    DWORD Err = m_GroupsDb.Get(i, &Id, &GroupName);
    while (Err == ERROR_SUCCESS)
    {
        i++;

        if (Id != m_HideGroupId)
            AddGroup(Id, GroupName);

        Err = m_GroupsDb.Get(i, &Id, &GroupName);
    }

    if (m_List.GetItemCount() > 0)
    {
        m_List.SelectItem(0);
        m_List.EnsureVisible(0, FALSE);
    }

    return bHandled = FALSE;
}

LRESULT CGroupsDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    if (Ret == TRUE)
        m_SelectedGroupId = Item.lParam;
    else
        m_SelectedGroupId = 0;      // 0 is an invalid ID

    m_GroupsDb.Close();
    m_List.Detach();
    return bHandled = FALSE;
}

LRESULT CGroupsDlg::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    OnSize();
    return bHandled = FALSE;
}

void CGroupsDlg::OnSize(void)
{
    CRect r;
    m_List.GetClientRect(&r);

    float NameColWidth = m_SelectMode == true ? 1.0f : OP_SYMBOL_WIDTH;
    m_List.SetColumnWidth(INDEX_NAME, (int)(r.Width() * NameColWidth));
    if (m_SelectMode == false)
    {
        m_List.SetColumnWidth(
            INDEX_OP,
            (int)(r.Width() * (1.0f - NameColWidth)));
    }
}

LRESULT CGroupsDlg::OnListDblClick(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    ATLASSERT(idCtrl == IDC_LIST);
    NMLISTVIEW *nml = (NMLISTVIEW *)pnmh;

    if (m_SelectMode == true)
    {
        LVITEM Item = {0};
        Item.mask = LVIF_PARAM;
        Item.iItem = nml->iItem;
        Item.iSubItem = 0;
        m_List.GetItem(&Item);

        EditGroup(Item.lParam);
    }

    return 0;
}

void CGroupsDlg::OnItem(int ItemId)
{
    if (m_SelectMode == true)
    {
        EndDialog(IDOK);
    }
    else
    {
        LVITEM Item = {0};
        Item.mask = LVIF_PARAM;
        Item.iItem = ItemId;
        Item.iSubItem = 0;
        m_List.GetItem(&Item);

        EditGroup(Item.lParam);
    }
}

LRESULT CGroupsDlg::OnListClick(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CGroupsDlg::OnListReturn(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CGroupsDlg::OnMenuNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    AddNewGroup();
    return 0;
}

void CGroupsDlg::AddNewGroup(void)
{
    CNewNameDlg NewNameDlg;
    int ret = NewNameDlg.DoModal();

    if (ret == ID_MENU_NEXT || ret == IDOK)
    {
        UINT AssignedId = 0;
        DWORD Err = m_GroupsDb.Add(NewNameDlg.GetName(), &AssignedId);
        if (Err != ERROR_SUCCESS)
        {
            ATLTRACE(_T("Add to database failed\n"));
            return;
        }

        AddGroup(AssignedId, NewNameDlg.GetName());

        CMembersDlg MembersDlg(AssignedId, NewNameDlg.GetName());
        MembersDlg.DoModal();
    }
}

void CGroupsDlg::AddGroup(UINT GroupId, CString &GroupName)
{
    LVITEM Item = { 0 };
    Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    Item.iItem = m_List.GetItemCount();
    Item.iSubItem = INDEX_NAME;
    Item.pszText = (LPTSTR)((LPCTSTR)GroupName);
    Item.iImage = 0;
    Item.lParam = GroupId;

    int NewIndex = m_List.InsertItem(&Item);
    if (NewIndex < 0)
    {
        ATLASSERT(!"InsertItem failed");
        return;
    }

    if (m_SelectMode == false)
    {
        Item.mask = LVIF_TEXT;
        Item.iItem = NewIndex;
        Item.iSubItem = INDEX_OP;
        Item.pszText = (TCHAR *)OP_SYMBOL;

        m_List.SetItem(&Item);
        m_List.SelectItem(NewIndex);
    }

    m_List.EnsureVisible(NewIndex, FALSE);
    m_List.SetFocus();
    OnSize();
}

void CGroupsDlg::EditGroup(UINT GroupId)
{
    CString GroupName;
    DWORD Err = m_GroupsDb.GetFromId(GroupId, &GroupName, NULL);
    if (Err == ERROR_SUCCESS)
    {
        CMembersDlg MembersDlg(GroupId, GroupName);
        MembersDlg.DoModal();
    }
}

LRESULT CGroupsDlg::OnMenuDelete(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    if (Ret == FALSE)
    {
        ATLTRACE(_T("No item selected to delete\n"));
        return 0;
    }

    int ret = Utils::MessageBoxRes(
        m_hWnd,
        IDR_MAINFRAME,
        IDS_CONFIRM_GROUP_DEL,
        MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2);
    if (ret == IDNO)
        return 0;

    UINT DbIndex = 0;
    DWORD Err = m_GroupsDb.GetFromId(Item.lParam, NULL, &DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to get db index\n"));
        return 0;
    }

    Err = m_GroupsDb.Delete(DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to delete from db\n"));
        return 0;
    }

    m_List.DeleteItem(Item.iItem);

    int ItemCount = m_List.GetItemCount();
    if (ItemCount > 0)
    {
        if (Item.iItem >= ItemCount)
            Item.iItem--;

        m_List.SelectItem(Item.iItem);
    }

    CMembersDb db;
    db.Open();
    db.DeleteByGroupId(Item.lParam);
    db.Close();

    OnSize();

    return 0;
}
